package services;

import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.encoding.TypeMapping;
import javax.xml.rpc.encoding.TypeMappingRegistry;

import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import org.example.www.communication.MailService.EMail;
import org.example.www.webBlogService.Blog;
import org.example.www.webBlogService.Comment;
import org.example.www.webBlogService.ImageWrapper;
import org.example.www.webBlogService.Post;
import org.example.www.webBlogService.User;
import org.example.www.webSuscriptionService.Feed;
import org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean;

/**
 * Extiende a JaxRpcPortProxyFactoryBean con el objetivo de declarar los mapeos
 * adicionales correspondientes a los tipos complejos devueltos por los
 * web-services.
 * 
 * @author Bulant - Hirsch - Maso Talou
 */
public class MyJaxRpcPortProxyFactoryBean extends JaxRpcPortProxyFactoryBean {

	/**
	 * El metodo es invocado luego del procesamiento de la creacion de la
	 * instancia. en el mismo se agrega el mapeo para los tipos de datos
	 * complejos utilizados en los web-services.
	 */
	@Override
	protected void postProcessJaxRpcService(Service service) {
		TypeMappingRegistry registry = service.getTypeMappingRegistry();
		TypeMapping mapping = registry.getDefaultTypeMapping();

		// Tipos del web-service communication (e-mail, chat)
		registerBeanMapping(
				"http://www.example.org/communication/MailService/", mapping,
				EMail.class, "EMail");
		registerBeanMapping(
				"http://www.example.org/communication/ChatService/", mapping,
				EMail.class, "ChatRoom");

		// Tipos del web-service countryInfo (routes, places)
		registerBeanMapping("http://www.example.org/countryInfoPlacesService/",
				mapping, org.example.www.countryInfoPlacesService.Place.class,
				"Place");
		registerBeanMapping("http://www.example.org/countryInfoRouteService/",
				mapping, org.example.www.countryInfoRouteService.Tramo.class,
				"Tramo");
		registerBeanMapping("http://www.example.org/countryInfo/", mapping,
				org.example.www.countryInfo.Location.class, "Location");
		registerBeanMapping("http://www.example.org/countryInfo/", mapping,
				org.example.www.countryInfo.Array.class, "Array");
		
		
		// Tipos del web-service web (blog, suscription)
		registerBeanMapping("http://www.example.org/webBlogService/", mapping,
				Blog.class, "Blog");
		registerBeanMapping("http://www.example.org/webBlogService/", mapping,
				Post.class, "Post");
		registerBeanMapping("http://www.example.org/webBlogService/", mapping,
				Comment.class, "Comment");
		registerBeanMapping("http://www.example.org/webBlogService/", mapping,
				ImageWrapper.class, "ImageWrapper");
		registerBeanMapping("http://www.example.org/webBlogService/", mapping,
				User.class, "User");
		registerBeanMapping("http://www.example.org/webSuscriptionService/",
				mapping, Feed.class, "Feed");

		String[] array = registry.getRegisteredEncodingStyleURIs();
		for (int i = 0; i < array.length; i++) {
			System.out.println("Encoding style: " + array[0]);
			registry.register(array[0], mapping);
		}

	}

	/**
	 * Registra de forma efectiva el mapeo.
	 */
	@SuppressWarnings("unchecked")
	protected void registerBeanMapping(String url, TypeMapping mapping,
			Class type, String name) {
		QName qName = new QName(url, name);
		mapping.register(type, qName, new BeanSerializerFactory(type, qName),
				new BeanDeserializerFactory(type, qName));
	}

}
